package org.ben.volatiletest;

import java.util.concurrent.TimeUnit;

public class VolatileTest {
    public static void main(String[] args) {
        Point p = new Point();
        PointThread1 p1 = new PointThread1(p);
        PointThread2 p2 = new PointThread2(p);
        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p2);
        t1.start();
        t2.start();
        try {
            TimeUnit.SECONDS.sleep(1);
            t1.interrupt();
            t2.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class PointThread1 implements Runnable {
    private Point p;

    PointThread1(Point p) {
        this.p = p;
    }

    public void run() {
        int i = 0;
        while (i++ < 9) {
            if(Thread.currentThread().isInterrupted())
                return;
            System.out.println("start from - " + Thread.currentThread().getName() + " " + p.getX());
            int x = p.getX();
            try {
                TimeUnit.MILLISECONDS.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            p.setX(x+1);
            System.out.println("end at - " + Thread.currentThread().getName() + " " + p.getX());
        }
        System.out.println("looped - " + Thread.currentThread().getName() + " " + i);
    }
}

class PointThread2 implements Runnable {
    private Point p;

    PointThread2(Point p) {
        this.p = p;
    }

    public void run() {
        int i = 0;
        while (i++ < 10) {
            if(Thread.currentThread().isInterrupted())
                return;
            System.out.println("start from - " + Thread.currentThread().getName() + " " + p.getX());
            int x = p.getX();
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            p.setX(x-1);
            System.out.println("end at - " + Thread.currentThread().getName() + " " + p.getX());
        }
        System.out.println("looped - " + Thread.currentThread().getName() + " " + i);
    }
}


class Point {
    private volatile int x;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }
}